package com.tanhua.app.service;



import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyuncs.utils.StringUtils;
import com.tanhua.api.db.UserInfoApi;
import com.tanhua.api.mongo.CommentApi;
import com.tanhua.api.mongo.PublishApi;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mogo.Comment;
import com.tanhua.domain.mogo.Publish;
import com.tanhua.domain.vo.CommentVo;
import com.tanhua.domain.vo.PageBeanVo;
import com.tanhua.domain.vo.PublishVo;
import com.tanhua.domain.vo.UserHolder;
import com.tanhua.template.OssTemplate;
import com.tanhua.utils.RelativeDateFormat;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class QuanziService {

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private PublishApi publishApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Reference
    private CommentApi commentApi;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    //发布动态方法
    public ResponseEntity movements(Publish publish, MultipartFile[] imageContent) throws IOException {

        //华为云审核动态
        //获取当前登录用户
        User user = UserHolder.getUser();
        publish.setUserId(user.getId());
        //设置审核状态码
        publish.setState(0); //0 未审核

        // 上传图片到oss中
        List<String> urlList = new ArrayList<>();//创建集合用于存放图片地址
        if (imageContent != null) {//如果上传图片不为空 遍历图片上传到oss并记录地址到集合中
            for (MultipartFile multipartFile : imageContent) {
                String oss_url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                urlList.add(oss_url);
            }
        }
        // 设置publish的属性
        publish.setMedias(urlList);//将图片地址封装给publish
        publish.setUserId(UserHolder.getUser().getId());//将用户id封装给publish
        // 调用服务保存方法
        String publishId = publishApi.save(publish);//save方法保存到mongodb数据库

        System.out.println("publishId:" + publishId);

        //保存动态id到中间件中去
        rocketMQTemplate.convertAndSend("tanhua_publish", publishId);
        return ResponseEntity.ok(null);
    }

    //查找个人动态方法
    public ResponseEntity findAlbumByPage(Integer page, Integer pagesize, Long userId) throws InvocationTargetException, IllegalAccessException {
        // 分页查询到当前登录用户的详情数据
        PageBeanVo pageBean = publishApi.findAlbumByPage(page, pagesize, userId);//
        List<Publish> items = (List<Publish>) pageBean.getItems();//获取Publish列表

        List<PublishVo> voList = new ArrayList<>();//PublishVo=UserInfo+Publish
        if (CollectionUtil.isNotEmpty(items)) {
            //用户
            UserInfo userInfo = userInfoApi.findUserInfo(userId);
            for (Publish publish : items) {
                // 封装userInfo--publishVo
                PublishVo publishVo = new PublishVo();
                BeanUtils.copyProperties(userInfo, publishVo);
                publishVo.setTags(userInfo.getTags().split(","));
                // 封装publish--publishVo
                BeanUtils.copyProperties(publish, publishVo);
                String[] ImageContent = publish.getMedias().toArray(new String[]{});
                publishVo.setImageContent(ImageContent);
                publishVo.setDistance("5.12公里");
                publishVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
                if (publish.getState() == 1) {
                    //信息是审核通过的
                    voList.add(publishVo);
                }
            }
        }
        //重新覆盖pageBean
        pageBean.setItems(voList);
        return ResponseEntity.ok(pageBean);
    }

    //查找朋友圈动态方法
    public ResponseEntity findTimeLineByPage(Integer page, Integer pagesize, Long userId) throws InvocationTargetException, IllegalAccessException {
        //分页查询好友时间线数据并封装到pagebean
        PageBeanVo pageBean = publishApi.findTimeLineByPage(page, pagesize, userId);//封装pagebean
        //获取publish列表
        List<Publish> items = (List<Publish>) pageBean.getItems();
        //封装PublishVO
        ArrayList<PublishVo> volist = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(items)) {
            //通过userId 查找UserInfo
            UserInfo userInfo = userInfoApi.findUserInfo(userId);
            for (Publish publish : items) {
                PublishVo publishVo = new PublishVo();
                //将userInfo封装到PublishVo
                BeanUtils.copyProperties(userInfo, publishVo);
                //前端数据类型不一致,单独封装Tags
                publishVo.setTags(userInfo.getTags().split(","));
                //封装publish到publishVo
                BeanUtils.copyProperties(publish, publishVo);
                //单独封装图片距离等数据
                String[] ImageContent = publish.getMedias().toArray(new String[]{});
                publishVo.setImageContent(ImageContent);
                publishVo.setDistance("666km");
                publishVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
                //信息审查通过
                if (publish.getState() == 1) {
                    volist.add(publishVo);
                }
            }
        }

        return ResponseEntity.ok(pageBean);
    }

    //查看推荐动态方法
    public ResponseEntity findRecommendByPage(Integer page, Integer pagesize, Long userid) {

        // 1 分页获取publish数据
        //先查redis有大数据给推荐的动态数据
        PageBeanVo pageBean=findFromBigDate(userid,page,pagesize);

        if (pageBean == null) {
            //当前登录用户没有历史行为 大数据没有推荐 还走以前默认的数据
            pageBean = publishApi.findRecommendByPage(page, pagesize, userid);
        }

        // 2 获取userInfo数据
        List<Publish> items = (List<Publish>) pageBean.getItems();

        List<PublishVo> publishVoList = new ArrayList<PublishVo>();
        if (CollectionUtil.isNotEmpty(items)) {
            for (Publish publish : items) {
                UserInfo userInfo = userInfoApi.findUserInfo(publish.getUserId());
                //3 数据封装publishVo
                PublishVo publishVo = new PublishVo();

                publishVo.setUserInfo(userInfo);
                publishVo.setPublish(publish);

                //点赞
                if (stringRedisTemplate.hasKey(StrUtil.format("publish_like_comment_{}_{}", userid, publish.getId()))) {
                    publishVo.setHasLiked(1); //是否点赞 0没点赞图标为灰色  1点赞了图标为高亮
                } else {
                    publishVo.setHasLiked(0); //是否点赞 0没点赞图标为灰色  1点赞了图标为高亮
                }

                //喜爱
                if (stringRedisTemplate.hasKey(StrUtil.format("publish_love_comment_{}_{}", userid, publish.getId()))) {
                    publishVo.setHasLoved(1); //是否点赞 0没点赞图标为灰色  1点赞了图标为高亮
                } else {
                    publishVo.setHasLoved(0); //是否点赞 0没点赞图标为灰色  1点赞了图标为高亮
                }

                publishVoList.add(publishVo);
            }
        }
        //4 返回pageBean<publishVo>
        pageBean.setItems(publishVoList);
        return ResponseEntity.ok(pageBean);
    }

    //点赞方法
    public ResponseEntity commentLike(String publishId) {
        //设置点赞的可变属性
        Comment comment = new Comment();//创建动态评论表操作对象
        comment.setPublishId(new ObjectId(publishId));//设置动态评论表publishid
        Long userId = UserHolder.getUser().getId();//获取用户id
        comment.setUserId(userId);//设置动态评论表用户id
        comment.setPubType(1);//设置评论内容类型： 1-对圈子动态操作 2-对视频操作 3-对评论操作
        comment.setCommentType(1);//设置评论类型，1-点赞，2-评论，3-喜欢
        Integer count = commentApi.save(comment);//

        //放入redis代表当前登录用户对某个动态点过赞 "comment_like_登录用户_动态id"
        stringRedisTemplate.opsForValue().set(StrUtil.format("publish_like_comment_{}_{}", userId, publishId), "1"); //1代表点赞

        return ResponseEntity.ok(count);
    }

    //取消点赞方法
    public ResponseEntity dislike(String publishId) {
        //设置点赞的可变属性
        Comment comment = new Comment();
        //设置动态评论表id
        comment.setPublishId(new ObjectId(publishId));
        Long userid = UserHolder.getUser().getId();
        comment.setUserId(userid);
        //设置评论内容类型
        comment.setPubType(1);//对圈子操作
        comment.setCommentType(1);//点赞

        Long userId = UserHolder.getUser().getId();
        comment.setUserId(userId);

        //取消点赞
        Integer count = commentApi.delete(comment);

        //redis标记删除
        stringRedisTemplate.delete(StrUtil.format("publish_like_comment_{}_{}", userId, publishId));

        return ResponseEntity.ok(count);


    }

    //喜欢方法
    public ResponseEntity commentLove(String publishId) {
        //设置喜欢的可变属性

        //创建动态评论表操作对象
        Comment comment = new Comment();
        //设置动态评论表
        comment.setPublishId(new ObjectId(publishId));
        //获取用户id
        Long userid = UserHolder.getUser().getId();
        comment.setUserId(userid);
        comment.setPubType(1);//对圈子操作
        comment.setCommentType(3);//喜欢
        Integer count = commentApi.save(comment);

        //将点过喜欢的用户id放入redis
        stringRedisTemplate.opsForValue().set(StrUtil.format("publish_love_comment_{}_{}", userid, publishId), "1");//1代表已经点过喜欢
        return ResponseEntity.ok(count);
    }

    //取消喜欢
    public ResponseEntity disLove(String publishId) {
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        Long userid = UserHolder.getUser().getId();
        comment.setUserId(userid);
        comment.setPubType(1);//对圈子
        comment.setCommentType(3);//喜欢

        Long userId = UserHolder.getUser().getId();
        comment.setUserId(userId);

        Integer count = commentApi.delete(comment);

        //redis标记给删除
        stringRedisTemplate.delete(StrUtil.format("publish_love_comment_{}_{}", userId, publishId));
        return ResponseEntity.ok(count);

    }

    //封装评论数据,查找动态id回显动态
    public ResponseEntity findByPublishId(String publishId) {
        // 根据publishId获取publish对象
        Publish publish = publishApi.findById(publishId);
        // 获取userInfo数据
        UserInfo userInfo = userInfoApi.findUserInfo(publish.getUserId());
        // 组装publishVo 进行返回
        PublishVo publishVo = new PublishVo();
        publishVo.setUserInfo(userInfo);
        publishVo.setPublish(publish);
        return ResponseEntity.ok(publishVo);
    }

    //回显动态评论
    public ResponseEntity findComments(String movementId, Integer page, Integer pagesize) {
        // 分页查询comment数据
        PageBeanVo pageBean = commentApi.findComments(movementId, page, pagesize);
        List<Comment> items = (List<Comment>) pageBean.getItems();
        List<CommentVo> commentVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(items)) {
            for (Comment comment : items) {
                // 查询userInfo的数据
                UserInfo userInfo = userInfoApi.findUserInfo(comment.getUserId());
                // 组装commentVo
                CommentVo commentVo = new CommentVo();
                BeanUtils.copyProperties(userInfo, commentVo);
                commentVo.setCreateDate(RelativeDateFormat.format(new Date(comment.getCreated())));
                commentVo.setLikeCount(comment.getLikeCount());
                commentVo.setContent(comment.getContent());
                commentVoList.add(commentVo);
            }
        }
        //封装pageBean返回
        pageBean.setItems(commentVoList);
        return ResponseEntity.ok(pageBean);

    }

    //新增动态评论
    public ResponseEntity addComments(String publishId, String content) {
        //设置点赞的可变属性
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        Long userId = UserHolder.getUser().getId();
        comment.setUserId(userId);
        comment.setPubType(1);
        comment.setCommentType(2);
        comment.setContent(content);
        Integer count = commentApi.save(comment);
        return ResponseEntity.ok(count);
    }



    //从redis中获取大数据提供的推荐数据
    private PageBeanVo findFromBigDate(Long userId, Integer page,Integer pagesize) {

        //根据用户id查询获取当前用户推荐的数据
        String values = stringRedisTemplate.opsForValue().get("QUANZI_PUBLISH_RECOMMEND_" + userId);
        //没有查到返回null
        if (StringUtils.isEmpty(values)) {
            return null;
        }
        //查询到推荐数据
        String[] publishStr = values.split(",");
        //分页数据
        int count = publishStr.length;//数组长度即分页总数
        //分页
        int star = (page - 1) * pagesize;
        if (star > count) {
            return null;
        }
        int end = page * pagesize;
        if (end > count) {
            end = count;
        }

        //循环遍历获取每一个publish对象
        List<Publish> list = new ArrayList<>();
        for (int i = star; i < end; i++) {
            Publish publish = publishApi.findById((publishStr[i]));
            list.add(publish);
        }
        return new PageBeanVo(page, pagesize, (long) count, list);
    }

}
